﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Documents;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Input;
using System.Diagnostics;

namespace Kinban
{
    public class AdornerDragDrop : Adorner
    {
        Grid _elementToShow = null; // the element to show on screen
        Point _position;//the _position where to draw the element
        private Size _elementSize;

        UIElement cannotDropElement;
        private UIElement _noDropControl;

        //constructor to drag and drop
        public AdornerDragDrop(UIElement element, UIElement elementToShow)
            : base(element)
        {
            //_noDropControl = cannotDrop;
            _elementToShow = CreateClone(elementToShow, null);
            FrameworkElement item = (FrameworkElement)elementToShow;
            _elementSize = new Size(item.ActualWidth, item.ActualHeight);


        }

        #region Force Layout system
        //make sure that the layout system knows of the element
        protected override Size MeasureOverride(Size constraint)
        {
            //Debug.WriteLine("{0}, {1}", constraint.Width, constraint.Height);
            _elementToShow.Measure(new Size(40, 40));
            //cannotDropElement.Measure(new Size(40, 40));
            return new Size(0, 0);
        }

        //make sure that the layout system knows of the element
        protected override Size ArrangeOverride(Size finalSize)
        {
            _elementToShow.Arrange(new Rect(-(_elementSize.Width * .5), -(_elementSize.Height * .5), _elementSize.Width, _elementSize.Height));
            //cannotDropElement.Arrange(new Rect(-(_elementSize.Width * .5), -(_elementSize.Height * .5), _elementSize.Width, _elementSize.Height));
            return _elementSize;
        }

        #endregion

        #region Force the visual to show
        //return the visual that we want to display
        protected override System.Windows.Media.Visual GetVisualChild(int index)
        {
            //_elementToShow.Opacity = .5;
            return _elementToShow;
        }

        //return the count of the visuals
        protected override int VisualChildrenCount
        {
            get { return 1; }
        }

        //moves the visual around
        public override GeneralTransform GetDesiredTransform(GeneralTransform transform)
        {
            //Debug.WriteLine("{0}, {1}", _position.X, _position.Y);
            GeneralTransformGroup group = new GeneralTransformGroup();
            group.Children.Add(transform);
            group.Children.Add(new TranslateTransform(_position.X, _position.Y));
            return group;
        }

        #endregion

        //updates the _position of the adorner
        public void UpdatePosition(Point point, bool canDrop)
        {
            if (canDrop)
            {
                _elementToShow.Opacity = 1;
            }
            else
            {
                _elementToShow.Opacity = .2;
            }

            _position = point;
            AdornerLayer parentLayer = Parent as AdornerLayer;
            if (parentLayer != null)
                parentLayer.Update(AdornedElement);
        }

        #region Helpers
        //create a clone of the element being dragged
        private static Grid CreateClone(UIElement element, UIElement noDrop)
        {
            Grid g = new Grid();
            //g.Children.Add(CreateClone(noDrop));
            g.Children.Add(CreateClone(element));

            return g;
        }

        private static ContentControl CreateClone(UIElement element)
        {
            ContentControl control = new ContentControl();
            ContentControl element1 = element as ContentControl;
            if (element1 != null)
            {
                control.Content = element1.Content;
                control.ContentTemplate = element1.ContentTemplate;
            }
            ContentPresenter element2 = element as ContentPresenter;
            if (element2 != null)
            {
                control.Content = element2.Content;
                control.ContentTemplate = element2.ContentTemplate;
            }

            return control;
        }

        #endregion
    }
}
